﻿/* Copyright 2010 Igor Francé
 * 
 * This file is part of ECMADoc (http://ecmadoc.codeplex.com).
 * 
 * ECMADoc is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * ECMADoc is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with ECMADoc. 
 * If not, see http://www.gnu.org/licenses/.
 */
namespace EcmaDoc.Core.Items
{
	using System;
	using System.Collections.Generic;
	using System.Linq;

	/// <summary>
	/// Implements a dictionary of <see cref="CodeItem">code items</see>.
	/// </summary>
	public class MemberDictionary : Dictionary<string, CodeItem>
	{
		/// <summary>
		/// Occurs when the dictionary contents changes.
		/// </summary>
		public event EventHandler Changed;

		/// <summary>
		/// Gets the total count of all members (counting recursively into all children) in all 
		/// <see cref="CodeItem"/> members in this dictionary.
		/// </summary>
		public int MemberCountRecursive
		{
			get
			{
				return Count + this.Values.Sum(ctx => ctx.MemberCountRecursive);
			}
		}

		/// <summary>
		/// Gets all members (collecting recursively from all children) in all <see cref="CodeItem"/> members in this dictionary.
		/// </summary>
		public List<CodeItem> MembersRecursive
		{
			get
			{
				List<CodeItem> all = new List<CodeItem>();
				all.AddRange(this.Values);

				foreach (CodeItem ctx in this.Values)
					all.AddRange(ctx.MembersRecursive);

				return all;
			}
		}

		/// <summary>
		/// Adds the specified <paramref name="codeItem"/> to this dictionary, using the specified <paramref name="key"/>.
		/// </summary>
		/// <param name="key">The key under which to add the item.</param>
		/// <param name="codeItem">The code item to add.</param>
		public new void Add(string key, CodeItem codeItem)
		{
			base.Add(key, codeItem);
			FireChangedEvent();
		}

		/// <summary>
		/// Removes all keys and values from this dictionary.
		/// </summary>
		public new void Clear()
		{
			base.Clear();
			FireChangedEvent();
		}

		/// <summary>
		/// Removes the element with the specified key from this dictionary.
		/// </summary>
		/// <param name="key">The key of the element to remove.</param>
		public new void Remove(string key)
		{
			base.Remove(key);
			FireChangedEvent();
		}

		/// <summary>
		/// Returns a <see cref="String"/> that represents this instance.
		/// </summary>
		/// <returns>
		/// A <see cref="String"/> that represents this instance.
		/// </returns>
		public override string ToString()
		{
			return string.Format("Count = {0}", Count);
		}

		private void FireChangedEvent()
		{
			if (Changed != null)
				Changed(this, EventArgs.Empty);
		}
	}
}
